package cn.sangedon.review.data.controller;

import cn.hutool.http.HttpUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.sangedon.review.common.constant.CacheConstant;
import cn.sangedon.review.common.domain.data.StockDayInfo;
import cn.sangedon.review.common.service.data.StockDayInfoService;
import cn.sangedon.review.common.util.Result;
import cn.sangedon.review.data.spider.impl.StockOfDayExcelSzSpider;
import cn.sangedon.review.data.utils.SpiderUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

/**
 * 遗漏的手动导入的一些数据接口
 */
@Slf4j
@Api
@RestController
@RequestMapping("import")
public class StockDataImportController {
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private StockDayInfoService stockDayInfoService;

    @Autowired
    private StockOfDayExcelSzSpider stockOfDayExcelSzSpider;

    @ApiOperation("导入上证A股公司上市信息")
    @PostMapping("stock/info")
    public Result importStockInfo(MultipartFile multipartFile, @RequestParam("type") String type) {
        try {
            ExcelReader reader = ExcelUtil.getReader(multipartFile.getInputStream());
            List<Map<String, Object>> maps = reader.readAll();
            redisTemplate.opsForHash().putIfAbsent(CacheConstant.COMPANY_INFO, type, maps);
            return Result.ok();
        } catch (Exception e) {
            return Result.error();
        }
    }

    @ApiOperation("手动同步上证A股遗漏的数据")
    @GetMapping("sync")
    public Result importStockDayInfo(@RequestParam("syncDate") String syncDate, @RequestParam("type") String type) {
        log.info("开始同步{}日交易数据", syncDate);
        JSONArray array = (JSONArray) redisTemplate.opsForHash().get(CacheConstant.COMPANY_INFO, type);
        List<String> imported = (ArrayList) redisTemplate.opsForHash().get("sange", "import" + syncDate);
        if (imported == null) {
            imported = new ArrayList<>();
        }
        String url = "http://query.sse.com.cn/commonQuery.do?sqlId=COMMON_SSE_CP_GPJCTPZ_GPLB_CJGK_MRGK_C&SEC_CODE=%s&TX_DATE=%s" +
                     "&TX_DATE_MON=&TX_DATE_YEAR=&_=1663660188626";
        List<StockDayInfo> list = new ArrayList<>();
        List<String> codeList = array.stream().map(e -> ((LinkedHashMap) e).get("B股代码").toString()).collect(Collectors.toList());

        codeList.removeAll(imported);
        log.info("total:{}", codeList.size());
        if (CollectionUtils.isEmpty(codeList)) {
            return Result.ok();
        }
        int i = 0;
        try {
            for (String code : codeList) {
                log.info("{}", ++i);
                String formatUrl = String.format(url, code, syncDate);
                String body = HttpUtil.createGet(formatUrl).header("Cookie",
                                                                   "gdp_user_id=gioenc-2e2ec5ab%2Cb6d0%2C5446%2C8665%2Cg2596b555476; " +
                                                                   "yfx_c_g_u_id_10000042=_ck22081717490412261267557745532; " +
                                                                   "yfx_mr_10000042=%3A%3Amarket_type_free_search%3A%3A%3A%3Abaidu%3A%3A" +
                                                                   "%3A" + "%3A%3A" + "%3A%3A" +
                                                                   "%3Awww.baidu.com%3A%3A%3A%3Apmf_from_free_search; yfx_key_10000042=; " +
                                                                   "ba17301551dcbaf9_gdp_session_id=6151924a-1125-4299-911e-2610c2226f96;" +
                                                                   " " + "yfx_f_l_v_t_10000042" +
                                                                   "=f_t_1660729744198__r_t_1663656368758__v_t_1663660188548__r_c_4; " +
                                                                   "ba17301551dcbaf9_gdp_session_id_6151924a-1125-4299-911e-2610c2226f96" +
                                                                   "=true").header("Referer", "http://www.sse.com.cn/").timeout(60000)
                                      .execute().body();
                JSONObject ret = JSONObject.parseObject(body);
                JSONArray result = ret.getJSONArray("result");
                if (result.size() <= 0) {
                    continue;
                }
                JSONObject object = (JSONObject) result.get(0);
                StockDayInfo stockDayInfo = new StockDayInfo();
                stockDayInfo.setCode(object.getString("SEC_CODE"));
                stockDayInfo.setName(object.getString("SEC_NAME"));
                stockDayInfo.setOpeningPrice(new BigDecimal(object.getString("OPEN_PRICE").replace(",", "")));
                stockDayInfo.setPeakPrice(new BigDecimal(object.getString("HIGH_PRICE").replace(",", "")));
                stockDayInfo.setBottomPrice(new BigDecimal(object.getString("LOW_PRICE").replace(",", "")));
                stockDayInfo.setClosingPrice(new BigDecimal(object.getString("CLOSE_PRICE").replace(",", "")));
                stockDayInfo.setChangeRate(new BigDecimal(object.getString("CHANGE_RATE").replace(",", "")));
                stockDayInfo.setTradingVolume(new BigDecimal(object.getString("TRADE_VOL").replace(",", "")).multiply(new BigDecimal(100)));
                stockDayInfo.setTradingAmount(new BigDecimal(object.getString("TRADE_AMT").replace(",", "")));
                stockDayInfo.setChangeAmount(new BigDecimal(object.getString("CHANGE_PRICE").replace(",", "")));
                stockDayInfo.setAmplitudeRate(object.getBigDecimal("CHANGE_RATE"));
                stockDayInfo.setTurnoverRate(object.getBigDecimal("TO_RATE"));
                stockDayInfo.setTradingDate(syncDate);
                list.add(stockDayInfo);
                SpiderUtil.randomDelay(5);
            }
        } catch (Exception e) {
            log.error("错误:{}", e);
        }
        for (StockDayInfo stockDayInfo : list) {
            try {
                stockDayInfoService.save(stockDayInfo);
                imported.add(stockDayInfo.getCode());
            } catch (Exception e) {
                log.info("{}日数据失败", stockDayInfo.getCode());
            }
        }
        //        stockDayInfoService.saveOrUpdateBatch(list);
        redisTemplate.opsForHash().put("sange", "import" + syncDate, imported);
        log.info("{}日数据同步成功", syncDate);
        return Result.ok();
    }

    @ApiOperation("手动同步深圳A股遗漏的数据")
    @PostMapping("syncSz")
    public Result syncSz(@RequestParam("syncDate") String syncDate, MultipartFile multipartFile) {
        try {
            InputStream inputStream = multipartFile.getInputStream();
            List<StockDayInfo> stockDayInfos = stockOfDayExcelSzSpider.parseExcel(inputStream);
            stockDayInfoService.saveOrUpdateBatch(stockDayInfos);
            return Result.ok();
        } catch (Exception e) {
            log.error("导入深圳日交易数据失败:{}", e);
            return Result.error();
        }
    }
}
